package sim.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;

import sim.model.Config;
import sim.model.Simulador;

public class VentanaPrincipal extends JFrame {

	private static final long serialVersionUID = 5244915407229005490L;

	private JPanel contentPane;
	private JTable table;
	private AbstractTableModel tableModel;
	private JPanel infoPanel;
	private JLabel lblMnimaCantidadDe;
	private JTextField txtMincantav;
	private JLabel lblPorcentajeDeDisponibilidad;
	private JTextField txtPorccantav;
	private JTextField txtCantMecanicos;
	private JPanel panelConfig;
	private JLabel lblIntRoturaAvion;
	private JTextField txtIntroturaavion;

	private JTextField txtIntcontrolavion;
	private JLabel lblSimular;
	private JTextField txtDiassimular;
	private JLabel lblDasO;
	private JTextField txtAvionessimular;
	private JLabel lblAviones;
	private JLabel lblCantMecnicosPor;
	private JTextField txtCantmecanicosrep;
	private JLabel lblMediaDistExp;
	private JTextField txtMediaReparacion;
	private JLabel label;

	/**
	 * Create the frame.
	 */
	public VentanaPrincipal() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 1000, 600);
		setTitle("Ejercicio 273 - Final Simulaciones - UTN FRC");

		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));

		setContentPane(contentPane);

		JScrollPane scrollPane = new JScrollPane();
		contentPane.add(scrollPane, BorderLayout.CENTER);

		this.tableModel = new DefaultTableModel(Config.getColumnNames(), 0);

		this.table = new JTable(this.tableModel);
		this.setColumnsWidths();
		this.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

		scrollPane.setViewportView(table);

		infoPanel = new JPanel();
		contentPane.add(infoPanel, BorderLayout.SOUTH);
		infoPanel.setPreferredSize(new Dimension(32, 96));
		infoPanel.setLayout(null);

		lblMnimaCantidadDe = new JLabel(
				"Mínima cantidad de aviones disponibles:");
		lblMnimaCantidadDe.setBounds(0, 0, 288, 32);
		infoPanel.add(lblMnimaCantidadDe);

		txtMincantav = new JTextField();
		txtMincantav.setBounds(300, 4, 100, 25);
		txtMincantav.setText("minCantAv");
		infoPanel.add(txtMincantav);
		txtMincantav.setColumns(10);

		lblPorcentajeDeDisponibilidad = new JLabel(
				"Porcentaje de disponibilidad de aviones:");
		lblPorcentajeDeDisponibilidad.setBounds(0, 31, 289, 32);
		infoPanel.add(lblPorcentajeDeDisponibilidad);

		txtPorccantav = new JTextField();
		txtPorccantav.setBounds(300, 35, 100, 25);
		txtPorccantav.setText("porcCantAv");
		infoPanel.add(txtPorccantav);
		txtPorccantav.setColumns(10);

		JLabel lblCantMecanicos = new JLabel("Cantidad de mecánicos necesaria:");
		lblCantMecanicos.setBounds(-1, 64, 289, 32);
		infoPanel.add(lblCantMecanicos);

		txtCantMecanicos = new JTextField();
		txtCantMecanicos.setText("cantMecanicos");
		txtCantMecanicos.setColumns(10);
		txtCantMecanicos.setBounds(300, 68, 100, 25);
		infoPanel.add(txtCantMecanicos);

		panelConfig = new JPanel();
		contentPane.add(panelConfig, BorderLayout.NORTH);
		panelConfig.setLayout(null);
		panelConfig.setPreferredSize(new Dimension(32, 105));

		lblIntRoturaAvion = new JLabel("Int. Rotura Avión:");
		lblIntRoturaAvion.setBounds(12, 16, 142, 15);
		panelConfig.add(lblIntRoturaAvion);

		txtIntroturaavion = new JTextField();
		txtIntroturaavion.setBounds(161, 12, 114, 19);
		txtIntroturaavion.setText("1.095890411");
		panelConfig.add(txtIntroturaavion);
		txtIntroturaavion.setColumns(10);

		JLabel lblIntControlAvion = new JLabel("Int. Control Avión:");
		lblIntControlAvion.setBounds(12, 41, 142, 15);
		panelConfig.add(lblIntControlAvion);

		txtIntcontrolavion = new JTextField();
		txtIntcontrolavion.setText("0.775");
		txtIntcontrolavion.setBounds(161, 37, 114, 19);
		panelConfig.add(txtIntcontrolavion);
		txtIntcontrolavion.setColumns(10);

		JButton btnSimular = new JButton("Simular");
		btnSimular.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				VentanaPrincipal.this.Simular();
			}
		});
		btnSimular.setBounds(688, 75, 117, 25);
		panelConfig.add(btnSimular);

		JPanel panel = new JPanel();
		panel.setBounds(12, 68, 428, 32);
		panelConfig.add(panel);

		lblSimular = new JLabel("Simular");
		panel.add(lblSimular);

		txtDiassimular = new JTextField();
		panel.add(txtDiassimular);
		txtDiassimular.setText("100");
		txtDiassimular.setColumns(10);

		lblDasO = new JLabel("días o ");
		panel.add(lblDasO);

		txtAvionessimular = new JTextField();
		panel.add(txtAvionessimular);
		txtAvionessimular.setText("1000");
		txtAvionessimular.setColumns(10);

		lblAviones = new JLabel("aviones");
		panel.add(lblAviones);

		lblCantMecnicosPor = new JLabel("Cant. Mecánicos por reparación:");
		lblCantMecnicosPor.setBounds(293, 16, 239, 15);
		panelConfig.add(lblCantMecnicosPor);

		txtCantmecanicosrep = new JTextField();
		txtCantmecanicosrep.setText("5");
		txtCantmecanicosrep.setBounds(545, 12, 114, 19);
		panelConfig.add(txtCantmecanicosrep);
		txtCantmecanicosrep.setColumns(10);

		lblMediaDistExp = new JLabel("Media Dist. Exp. Neg. Reparación:");
		lblMediaDistExp.setBounds(293, 41, 239, 15);
		panelConfig.add(lblMediaDistExp);

		txtMediaReparacion = new JTextField();
		txtMediaReparacion.setText("7");
		txtMediaReparacion.setBounds(578, 37, 81, 19);
		panelConfig.add(txtMediaReparacion);
		txtMediaReparacion.setColumns(10);

		label = new JLabel("1 / ");
		label.setBounds(555, 41, 26, 15);
		panelConfig.add(label);

		// -------------------------------------------------------------------
		// Generamos una config temporal para setear los texts
		Config tmpConfig = new Config();
//		this.txtIntroturaavion.setText(String.valueOf(tmpConfig
//				.getIntervaloRoturaAvion()));
		this.txtIntcontrolavion.setText(String.valueOf(tmpConfig
				.getIntervaloControlAvion()));
		this.txtCantmecanicosrep.setText(String.valueOf(tmpConfig
				.getCantMecanicosParaReparacion()));

		this.txtDiassimular.setText(String.valueOf(tmpConfig
				.getSimulacionDias()));
		this.txtAvionessimular.setText(String.valueOf(tmpConfig
				.getSimulacionAviones()));

		this.txtMediaReparacion.setText(String.valueOf(1 / tmpConfig
				.getMediaReparacion()));
		tmpConfig = null;
		// -------------------------------------------------------------------

	}

	/**
	 * Agrega una fila a la tabla de la ventana. Se le debe pasar por parámetro
	 * cada columna de la tabla en un objeto Vector. El vector debe contener los
	 * siguientes datos:
	 * <ul>
	 * <li>Días (Clock)
	 * <li>Evento
	 * <li>Próx avión roto
	 * <li>Próx avión control
	 * <li>Cant aviones en raparac
	 * <li>Cant aviones disponibles
	 * <li>Macanicos reparando
	 * <li>RND reparacion
	 * <li>Tiempo reparacion
	 * <li>Próx fin reparación
	 * <li>Max cant mec trab
	 * <li>[Una lista con los finales de reparacion de todos los aviones en
	 * reparación]
	 * </ul>
	 * 
	 * @param row
	 *            Un objeto Vector con los datos de las columnas de la tabla.
	 */
	public void addRow(Vector<Object> row) {
		DefaultTableModel model = (DefaultTableModel) table.getModel();
		model.addRow(row);
		table.repaint();
	}

	/**
	 * Limpia la tabla para comenzar una nueva simulación.
	 */
	public void clearTable() {
		DefaultTableModel model = (DefaultTableModel) table.getModel();
		model.getDataVector().removeAllElements();
		table.repaint();
	}

	/**
	 * Actualiza los cuadros de textos del formulario con los valores
	 * solicitados.
	 * 
	 * @param porcCantAv
	 *            El porcentaje de tiempo que la mínima cantidad preferente de
	 *            aviones (minCantAv) debe estar disponible.
	 * @param minCantAv
	 *            La cantidad de aviones que deben estar disponibles
	 *            preferentemente.
	 * @param cantMecanicos
	 *            La máxima cantidad de mecanicos que se requiere para mantener
	 *            la mínima cantidad preferente de aviones (minCantAv) el
	 *            porcentaje de tiempo establecido (porcCantAv).
	 */
	public void setInfoTexts(double porcCantAv, int minCantAv, int cantMecanicos) {
		final String dblFormat = "%,.2f";
		final String intFormat = "%d";
		this.txtPorccantav.setText(String.format(dblFormat + "%%", porcCantAv));
		this.txtMincantav.setText(String.format(intFormat, minCantAv));
		this.txtCantMecanicos.setText(String.format(intFormat, cantMecanicos));
	}

	/**
	 * Metodo que configura el ancho de algunas columnas para adaptarlas al
	 * contenido
	 */
	private void setColumnsWidths() {

		// Background Color gris para algunas columnas.

		// Clock
		this.table.getColumnModel().getColumn(0).setPreferredWidth(50);

		// Cant aviones en raparac
		this.table.getColumnModel().getColumn(5).setPreferredWidth(90);

		// Cant aviones disponibles
		this.table.getColumnModel().getColumn(6).setPreferredWidth(90);

		// Maxima cantidad de mecanicos trabajando
		this.table.getColumnModel().getColumn(11).setPreferredWidth(65);

		// Cant Aviones reparados
		this.table.getColumnModel().getColumn(12).setPreferredWidth(65);

		// prox fin rep Av
		final int anchoColmnasFinRepAv = 65;
		for (int i = 13; i < Config.getCantColumnasFinrepav() + 13; i++) {
			this.table.getColumnModel().getColumn(i)
					.setPreferredWidth(anchoColmnasFinRepAv);
		}
	}

	/**
	 * Comienza la simulación
	 */
	private void Simular() {
		Simulador simulador = new Simulador(this);
		simulador.setIntervaloRoturaAvion(Double
				.valueOf(this.txtIntroturaavion.getText()));
		simulador.setIntervaloControlAvion(Double
				.valueOf(this.txtIntcontrolavion.getText()));
		simulador.setSimulationEnd(
				Double.valueOf(this.txtDiassimular.getText()),
				Integer.valueOf(this.txtAvionessimular.getText()));
		simulador.setCantMecanicosParaReparacion(Integer
				.valueOf(this.txtCantmecanicosrep.getText()));
		simulador.setMediaReparación(1 / Double.valueOf(this.txtMediaReparacion
				.getText()));

		Thread tSimulador = new Thread(simulador);
		tSimulador.run();
	}
}
